#include "fb_device.h"


#define FB_DEVICE_NAME "/dev/fb0"

fb_device::fb_device()
{
	device_name = FB_DEVICE_NAME;
	i32FBFd = -1;
}
fb_device::fb_device(string dev_name)
{
	device_name = dev_name;
	i32FBFd = -1;
	
}
int fb_device::fb_get_width()
{
	return s_i32FBWidth;
}
int fb_device::fb_get_height()
{
	return s_i32FBHeight;
}

int fb_device::InitFBDevice(uint8_t **ppu8FBBuf,uint32_t *pu32FBBufSize)
{
	uint8_t *pu8FBBuf;
	static struct fb_var_screeninfo sVar;

	*ppu8FBBuf = (uint8_t *)MAP_FAILED;
	*pu32FBBufSize = 0;
	
	i32FBFd = open(device_name.c_str(), O_RDWR);
	if(i32FBFd < 0){
		printf("Open FB fail\n");
		return -1;
	}

	printf("fb open successful\n");
	if (ioctl(i32FBFd, FBIOGET_VSCREENINFO, &sVar) < 0) {
		printf("ioctl FBIOGET_VSCREENINFO \n");
		close(i32FBFd);
		return -1;
	}

	
	s_i32FBWidth = sVar.xres;
	s_i32FBHeight = sVar.yres;

	if(OSDCheckExist(i32FBFd))
	{
		pu8FBBuf = (uint8_t *)mmap( NULL, s_i32FBWidth*s_i32FBHeight*2*2 , PROT_READ|PROT_WRITE, MAP_SHARED, i32FBFd, 0 );
		if (MAP_FAILED == pu8FBBuf) {
			close(i32FBFd);		
			return -1;
		}
		*pu32FBBufSize = s_i32FBWidth*s_i32FBHeight*2*2 ;
		OSDInit(i32FBFd, s_i32FBWidth, s_i32FBHeight, pu8FBBuf + (s_i32FBWidth*s_i32FBHeight*2));	
	}
	else
	{
		pu8FBBuf = (uint8_t *)mmap( NULL, s_i32FBWidth*s_i32FBHeight*2 , PROT_READ|PROT_WRITE, MAP_SHARED, i32FBFd, 0 );
		if ((unsigned char*)-1 == pu8FBBuf) {
			close(i32FBFd);
			return -1;
		}
		*pu32FBBufSize = s_i32FBWidth*s_i32FBHeight*2;
	}

	ioctl(i32FBFd, IOCTL_LCD_DISABLE_INT, 0);
	//usleep(50000);		/* Delay 50ms to not update the off-line buffer to on line buffer */


	ioctl(i32FBFd, VIDEO_FORMAT_CHANGE, DISPLAY_MODE_YCBYCR);
	//2012-0808 wmemset((wchar_t *)pu8FBBuf, 0x80108010, (s_i32FBWidth*s_i32FBHeight*2)/4); 	

	ioctl(i32FBFd, IOCTL_LCD_ENABLE_INT, 0);
	*ppu8FBBuf = pu8FBBuf; 
	return i32FBFd;
}
void fb_device::ClearFB(	int32_t i32FBFd,uint8_t *pu8FBBufAddr)
{
	ioctl(i32FBFd, IOCTL_LCD_DISABLE_INT, 0);	
	wmemset((wchar_t *)pu8FBBufAddr, 0x80008000, (s_i32FBWidth*s_i32FBHeight*2)/4);
	ioctl(i32FBFd, IOCTL_LCD_ENABLE_INT, 0);
}

void fb_device::OSDInit(int i32FBFd,int i32Width,int i32Height,uint8_t *pu8OSDBuff)
{
	// STEP: set color key to white(0xFFFF)
		
	osd_cmd_t sOSDCmd;
	FILE *fpOSDImg = NULL;	

	sOSDCmd.cmd = OSD_SetTrans;
	sOSDCmd.color = 0xffff;
	ioctl(i32FBFd, OSD_SEND_CMD, (unsigned long) &sOSDCmd);
	
	// STEP: clear all of OSD buffer
	sOSDCmd.cmd = OSD_Open;			
	ioctl(i32FBFd, OSD_SEND_CMD, (unsigned long) &sOSDCmd);
	sOSDCmd.cmd = OSD_Clear;    			
	ioctl(i32FBFd, OSD_SEND_CMD, (unsigned long) &sOSDCmd);

	sOSDCmd.cmd = OSD_Fill;
	sOSDCmd.x0 = 0;		// OSD_Fill command test
	sOSDCmd.y0 = 0;
	sOSDCmd.x0_size = i32Width;
	sOSDCmd.y0_size = i32Height;
	sOSDCmd.color = 0x0;
	ioctl(i32FBFd, OSD_SEND_CMD, (unsigned long) &sOSDCmd);

	// STEP: enable OSD
	sOSDCmd.cmd = OSD_Show;
	ioctl(i32FBFd, OSD_SEND_CMD, (unsigned long) &sOSDCmd);

	// OSD is replaced by another image 
	sOSDCmd.cmd = OSD_SetTrans;		
	sOSDCmd.color = 0x0000;		
	ioctl(i32FBFd, OSD_SEND_CMD, (unsigned long) &sOSDCmd);
	

	if( (i32Width==480) && (i32Height==272))
		fpOSDImg = fopen("OSD_480_272_RGB565.bin", "r");	
	if( (i32Width==320) && (i32Height==240))
		fpOSDImg = fopen("OSD_320_240_RGB565.dat", "r");	
	if( (i32Width==800) && (i32Height==480))
		fpOSDImg = fopen("OSD_800_480_RGB565.dat", "r");

	if(fpOSDImg == NULL){
		printf("open OSD FILE fail !! \n");
		return;
	}  
    
	if( fread(pu8OSDBuff, (i32Width*i32Height*2), 1, fpOSDImg) <= 0){
		printf("Cannot Read the OSD File!\n");
		return;
	}
	fclose(fpOSDImg); 

}
int fb_device::OSDCheckExist(int i32FBFd)
{

#if 0
	osd_cmd_t sOSDCmd;
	int i32Err;
	sOSDCmd.cmd = OSD_Open;			
	i32Err = ioctl(i32FBFd,OSD_SEND_CMD, (unsigned long) &sOSDCmd);	
	if(i32Err >= 0){
		DEBUG_PRINT("OSD enable\n");
		return 1;	
	}
	else{
		DEBUG_PRINT("OSD disable\n");
		return 0;	
	}
#else
	return 0;
#endif


}
#if 0
int main()
{
	return 0;
}
#endif
